package com.alks.function.service.impl.product;

import com.alks.common.aop.AutoPageAop;
import com.alks.common.data.thread.UserIdThread;
import com.alks.common.service.RedisService;
import com.alks.entity.data.entity.PcMtlAccPack;
import com.alks.entity.data.entity.PcSlipDetailPart;
import com.alks.entity.data.entity.PcSlipTempPart;
import com.alks.entity.data.entity.PcSlipTempPartResp;
import com.alks.entity.data.response.ResponseInfo;
import com.alks.function.data.request.stock.PcOutMaterialReq;
import com.alks.function.data.request.stock.PcSlipTempPartOReq;
import com.alks.function.data.request.stock.PcSlipTempPartReq;
import com.alks.function.data.request.stockdept.pcfactorystockwork.CsmDetRequest;
import com.alks.function.mapper.product.SdMaterialMapper;
import com.alks.function.service.product.SdMaterialService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author:hxl
 * @create: 2023-12-16 17:13
 * @Description:
 */

@Service
public class SdMaterialServiceImpl implements SdMaterialService {
    @Autowired
    private SdMaterialMapper sdMaterialMapper;

    @Autowired
    private RedisService redisService;
    @Override
    public ResponseInfo sdMaterialList() {
        return ResponseInfo.ok(sdMaterialMapper.sdMaterialList(UserIdThread.get().getLoginName()));
    }

    @Override
    public ResponseInfo insertMaterialPart(String mtlNo) {
        //
        if(sdMaterialMapper.selectByMtlNoI(mtlNo,UserIdThread.get().getLoginName())>0){
            return ResponseInfo.error("物料编码已存在");
        }
        Integer max = sdMaterialMapper.getPcSlipTempPartMax(UserIdThread.get().getLoginName());
        if (max==null){
            max=0;
        }
        max++;
        sdMaterialMapper.insertMaterialPart(mtlNo,UserIdThread.get().getLoginName(),max);
        return ResponseInfo.ok() ;
    }

    @Override
    @Transactional
    public ResponseInfo insertBatchPcPart(PcSlipTempPartReq req) {
        if (req.getList()==null||req.getList().isEmpty()){
            return ResponseInfo.error("入库批处理数据不能为空");
        }
        String name = UserIdThread.get().getLoginName();
        String slipNo = redisService.slipNoCreat("D");
        List<String> list = req.getList();
        sdMaterialMapper.insertBatchPcPart(req,slipNo,name);
        for (String string : list) {
            PcMtlAccPack acc = new PcMtlAccPack();
            //获取当前数据的qty 是第一次插入 不是第一次更新
            BigDecimal currQty = sdMaterialMapper.getByPcMtlAcc(string);
            if (currQty==null){
                sdMaterialMapper.insertIntoAccPart(string);
                break;
            }
            BigDecimal addQty = sdMaterialMapper.getTempPartQty(string);
            acc.setInQty(currQty.add(addQty));
            acc.setStkQty(currQty.add(addQty));
            //数据更新
            sdMaterialMapper.updateAccPart(acc,string);
        }
        sdMaterialMapper.deleteTempPartFromUser(name);
        return ResponseInfo.ok();
    }

    @Override
    public ResponseInfo updatePcSlipTempPart(PcSlipTempPartResp req) {
        String choose = "I";
        sdMaterialMapper.updatePcSlipTempPart(req,choose);
        return ResponseInfo.ok();
    }

    @Override
    public ResponseInfo pcSlipDetailPartList(CsmDetRequest req) {
        List<PcSlipDetailPart> list =  sdMaterialMapper.pcSlipDetailPartList(req,UserIdThread.get().getLoginName());
        return ResponseInfo.ok(list);
    }

    @Override
    public ResponseInfo deletePcSlipDetailPart(String mtlNo) {
        sdMaterialMapper.deletePcSlipDetailPart(mtlNo,UserIdThread.get().getLoginName());
        return ResponseInfo.ok();
    }

    @Override
    public ResponseInfo outMaterialList(String typeNo, String typeName, String mtlName, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum,pageSize);
        Map<String, Object> map = new HashMap<>();
        List<Map<String,Object>> list = sdMaterialMapper.outMaterialList(typeNo,typeName,mtlName);
        Page<Map<String,Object>> page = (Page<Map<String, Object>>) list;
        map.put("list",list);
        map.put("total",page.getTotal());
        return ResponseInfo.ok(map);
    }

    @Override
    public ResponseInfo outMaterialInTemp(String mtlNo) {
        String name = UserIdThread.get().getLoginName();
        if(sdMaterialMapper.selectByMtlNoO(mtlNo,name)>0){
            return ResponseInfo.error("物料编码已存在");
        }
        BigDecimal num = sdMaterialMapper.getStockByacc(mtlNo);
        if (num == null || num.intValue()<=0){
            return ResponseInfo.error("库存数量小于0");
        }
        Integer max = sdMaterialMapper.getPcSlipTempPartOMax(UserIdThread.get().getLoginName());
        if (max==null){
            max=0;
        }
        max++;
        sdMaterialMapper.insertIntoOutTemp(mtlNo,name,max);
        return ResponseInfo.ok("插入成功");
    }

    @Override
    public ResponseInfo pcSlipTempPartOutList() {
        List<PcSlipTempPart> list = sdMaterialMapper.pcSlipTempPartOutList(UserIdThread.get().getLoginName());
        return ResponseInfo.ok(list);
    }

    @Override
    @Transactional
    public ResponseInfo outBatchInPcSlipTemp(PcSlipTempPartOReq req) {
        String slipNo = redisService.slipNoCreat("D");
        String name = UserIdThread.get().getLoginName();
        List<PcSlipTempPart> list = req.getList();
        //出库批处理 判断数量 是否小于库存量
        List<PcSlipTempPart> collect = list.stream().filter(x -> x.getQty() == null || x.getQty().compareTo(x.getStkQty())>0).collect(Collectors.toList());
        if (!collect.isEmpty()){
            return ResponseInfo.error("数量不能为空或者数量大于库存数量");
        }
        if (req.getSlipReason()==null||req.getDeptNo()==null||req.getDeptName()==null||req.getSlipDate()==null){
            return ResponseInfo.error("出库原因、部门不能为空");
        }
        //插入到PC_SLIP_DETAIL_PART 表中生成slipNo 出库单号
        sdMaterialMapper.insertIntoOutDetail(req,name,slipNo);
        //减去相应的数量
        for (PcSlipTempPart pcSlipTempPart : list) {
            //出库数量
            String mtlNo = pcSlipTempPart.getMtlNo();
            BigDecimal num = sdMaterialMapper.getOutQty(mtlNo);
            num = num == null?new BigDecimal("0").add(pcSlipTempPart.getQty()):num.add(pcSlipTempPart.getQty());
            sdMaterialMapper.subtractPcSlipDetailPart(num,mtlNo);
        }
        //删除待出库表中数据
        sdMaterialMapper.deletePcSlipTempO(name);
        return ResponseInfo.ok("出库成功");
    }

    @Override
    public ResponseInfo updatePcSlipTemp(PcSlipTempPart req) {
        PcSlipTempPartResp resp = new PcSlipTempPartResp();
        resp.setMtlNo(req.getMtlNo());
        resp.setQty(req.getQty());
        resp.setRemark(req.getRemark());
        String choose = "O";
        sdMaterialMapper.updatePcSlipTempPart(resp,choose);
        return ResponseInfo.ok("修改成功");
    }

    @Override
    public ResponseInfo deletePcSlipTemp(String mtlNo) {
        sdMaterialMapper.deletePcSlipTemp(mtlNo,UserIdThread.get().getLoginName());
        return ResponseInfo.ok("删除成功");
    }

    @Override
    @AutoPageAop
    public ResponseInfo pcSlipDetailOutList(PcOutMaterialReq req) {
        HashMap<String, Object> map = new HashMap<>();
        List<PcSlipDetailPart> list = sdMaterialMapper.pcSlipDetailOutList(req,UserIdThread.get().getLoginName());
        Page<PcSlipDetailPart> page = (Page<PcSlipDetailPart>) list;
        map.put("list",list);
        map.put("total",page.getTotal());
        return ResponseInfo.ok(map);
    }

    @Override
    @Transactional
    public ResponseInfo deletePcSlipDetailPartO(PcSlipDetailPart req) {
        String mtlNo = req.getMtlNo();
        String slipNo = req.getSlipNo();
        BigDecimal qty = req.getQty();
        String name = UserIdThread.get().getLoginName();
        sdMaterialMapper.deletePcSlipDetailPartO(slipNo,mtlNo,name);
        BigDecimal outQty = sdMaterialMapper.getOutQty(mtlNo);
        BigDecimal stkQty = sdMaterialMapper.getStockByacc(mtlNo);
        qty = qty==null?new BigDecimal(0):qty;
        outQty = outQty.subtract(qty);
        stkQty = stkQty.add(qty);
        sdMaterialMapper.updatePcAcc(mtlNo,outQty,stkQty);
        return ResponseInfo.ok("删除成功");
    }
}
